﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using personalplaner.business.extensions;
using personalplaner.business.stamm;
using personalplaner.common.mvvm;
using personalplaner.common.mvvm.commands;
using personalplaner.common.mvvm.common;
using personalplaner.servicemodel.dataaccess;
using personalplaner.gui.common;
using personalplaner.gui.stamm.windows;
using personalplaner.business;


namespace personalplaner.gui.stamm.viewmodels
{
    public class DienstStammViewModel : BaseViewModel
    {
		public DienstStammViewModel(DependencyObject parent)
            : base(parent)
        {
        }

		public override void Loaded()
		{
			var mw = GetService<IMainWindowDisplayContainer>();
			mw.IsWaitVisible = false;
		}

        #region Commands

        ICommand _okcommand;
        public ICommand OkCommand
        {
            get
            {
                if (_okcommand == null)
                    _okcommand = new RelayCommand(OnOkCommand);
                return _okcommand;
            }
        }

        private void OnOkCommand(object parameter)
        {
            // call all mediator suscriptions to refresh the Dienste
			Mediator.NotifyColleagues("RefreshDienste");

			var wnd = Parent as Window;
			if (wnd != null)
			{
				wnd.DialogResult = true;
				wnd.Close();
				return;
			}

			var mw = GetService<IMainWindowDisplayContainer>();
			mw.MoveToPreviousView();
        }

        ICommand _cancelcommand;
        public ICommand CancelCommand
        {
            get
            {
                if (_cancelcommand == null)
                    _cancelcommand = new RelayCommand(OnCancelCommand);
                return _cancelcommand;
            }
        }

        private void OnCancelCommand(object parameter)
        {
            // call all mediator suscriptions to refresh the Dienste
			Mediator.NotifyColleagues("RefreshDienste");

			var wnd = Parent as Window;
			if (wnd != null)
			{
				wnd.DialogResult = false;
				wnd.Close();
				return;
			}

			var mw = GetService<IMainWindowDisplayContainer>();
			mw.MoveToPreviousView();
        }

        ICommand _savecommand;
        public ICommand SaveCommand
        {
            get
            {
                if (_savecommand == null)
					_savecommand = new RelayCommand(OnSave, parameter => SelectedDienst != null);
                return _savecommand;
            }
        }

        private void OnSave(object parameter)
        {
			if (!SelectedDienst.IsValid)
			{
				switch (SelectedDienst.Error)
				{
					case "Color":
					case "Name":
						if (string.IsNullOrEmpty(SelectedDienst.Name) && SelectedDienst.Color == null)
						{
							MessageBox.Show(Window.GetWindow(Parent), "Es wurde kein Anzeigename oder Farbe definiert.\nBitte geben Sie entweder einen Namen oder eine Farbe an.", "Kein Anzeigename oder Farbe", MessageBoxButton.OK, MessageBoxImage.Asterisk);
							RaiseMoveFocus(SelectedDienst.Error);
							return;
						}
						break;
					default:
						MessageBox.Show(string.Format("Für das Feld {0} wurde kein Wert angegeben.", SelectedDienst.Error), "Kein Wert", MessageBoxButton.OK, MessageBoxImage.Asterisk);
						RaiseMoveFocus(SelectedDienst.Error);
						break;
				}
				return;
			}

			var da = GetService<IDiensteDataAccess>();
			if (!SelectedDienst.IsNew)
				da.UpdateDienst(SelectedDienst);
			else
			{
				SelectedDienst.DienstID = da.SaveDienst(SelectedDienst);
                SelectedDienst.ID = SelectedDienst.DienstID;
				Dienste.Add(SelectedDienst);
			}

            // call all mediator suscriptions to refresh the Dienste
            Mediator.NotifyColleagues("RefreshDienste");
        }

        ICommand _newcommand;
        public ICommand NewCommand
        {
            get
            {
                if (_newcommand == null)
                    _newcommand = new RelayCommand(OnNew);
                return _newcommand;
            }
        }

        private void OnNew(object parameter)
        {
            SelectedDienst = new Dienst
            {
                IsGerechnet = true
            };
            RaiseMoveFocus("Name");
        }

		ICommand _deleteCommand;
		public ICommand DeleteCommand
        {
            get
            {
				if (_deleteCommand == null)
					_deleteCommand = new RelayCommand(OnDelete, param => SelectedDienst != null && !SelectedDienst.IsNew);
				return _deleteCommand;
            }
        }

		private void OnDelete(object parameter)
		{
			if (MessageBox.Show(string.Format("Sind Sie sicher dass Sie den Dienst: {0}\nwirklich löschen möchten", SelectedDienst.Name),
					"Dienst löschen?", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
				return;

			var da = GetService<IDiensteDataAccess>();
			da.DeleteDienst(SelectedDienst.DienstID);

			//var tmp = SelectedDienst;
			//SelectedDienst = null;
			//Dienste.Remove(tmp);
			_dienste = null;
			RaisePropertyChanged("Dienste");

            // call all mediator suscriptions to refresh the Dienste
            Mediator.NotifyColleagues("RefreshDienste");
		}

        ICommand _addBereichTimeCommand;
        public ICommand AddBereichCommand
        {
            get
            {
                if (_addBereichTimeCommand == null)
                    _addBereichTimeCommand = new RelayCommand(OnAddBereich, param => SelectedDienst != null && !SelectedDienst.IsNew);
                return _addBereichTimeCommand;
            }
        }

        private void OnAddBereich(object param)
        {
			var wnd = new DienstZeitWizard(SelectedDienst.DienstID)
            {
                Owner = Window.GetWindow(Parent)
            };

            if (wnd.ShowDialog() != true)
                return;

			var da = GetService<IDiensteDataAccess>();
			DienstZeiten = da.GetDienstZeiten(SelectedDienst.DienstID);
        }

		ICommand _removeBereichCommand;
		public ICommand RemoveBereichCommand
		{
			get
			{
				if (_removeBereichCommand == null)
					_removeBereichCommand = new RelayCommand<DienstZeitCollection>(OnRemoveBereich);
				return _removeBereichCommand;
			}
		}

		private void OnRemoveBereich(DienstZeitCollection param)
		{
			if (param == null)
				return;

			var da = GetService<IDiensteDataAccess>();
			da.DeleteDienstZeit(SelectedDienst.DienstID, param);

			// reload the times
			DienstZeiten = da.GetDienstZeiten(SelectedDienst.DienstID);
		}

        //ICommand _addTimeCommand;
        //public ICommand AddTimeCommand
        //{
        //    get
        //    {
        //        if (_addTimeCommand == null)
        //            _addTimeCommand = new RelayCommand<DienstZeitCollection>(OnAddTime);
        //        return _addTimeCommand;
        //    }
        //}

        //private void OnAddTime(DienstZeitCollection param)
        //{
        //    //var wnd = new DienstZeitDialog
        //    //{
        //    //    Owner = Window.GetWindow(Parent)
        //    //};

        //    //if (wnd.ShowDialog() != true)
        //    //    return;
        //}

		ICommand _editTimeCommand;
		public ICommand EditTimeCommand
		{
			get
			{
				if (_editTimeCommand == null)
					_editTimeCommand = new RelayCommand<DienstZeitCollection>(OnEditTime);
				return _editTimeCommand;
			}
		}

		private void OnEditTime(DienstZeitCollection param)
		{
			if (param == null)
				return;

			var wnd = new DienstZeitWizard(SelectedDienst.DienstID)
            {
                Owner = Window.GetWindow(Parent),
				UpdateCollection = param
            };

            if (wnd.ShowDialog() != true)
                return;

			var da = GetService<IDiensteDataAccess>();
			DienstZeiten = da.GetDienstZeiten(SelectedDienst.DienstID);
		}

    	ICommand _collapseTimeCommand;
		public ICommand CollapseTimeCommand
		{
			get
			{
				if (_collapseTimeCommand == null)
					_collapseTimeCommand = new RelayCommand<DienstZeitCollection>(OnCollapseTime);
				return _collapseTimeCommand;
			}
		}

		private void OnCollapseTime(DienstZeitCollection parameter)
		{
			if (parameter == null)
				return;

			parameter.IsExpanded = !parameter.IsExpanded;
		}

    	#endregion

        #region Properties

		IList<Dienst> _dienste;
		public IList<Dienst> Dienste
		{
			get
			{
				if (Designer.IsDesignMode)
					return new List<Dienst>();

				if (_dienste == null)
				{
					//get the data access via the service locator.
					var da = GetService<IDiensteDataAccess>();
					var lst = da.GetDienste(false, false);
					_dienste = lst != null ? new ObservableCollection<Dienst>(lst) : new ObservableCollection<Dienst>();
				}
				return _dienste;
			}
			set
			{
				_dienste = value;
				RaisePropertyChanged("Dienste");
			}
		}

		Dienst _selectedDienst;
    	public Dienst SelectedDienst
    	{
    		get
    		{
    			return _selectedDienst;
    		}
    		set
    		{
    			_selectedDienst = value;
    			RaisePropertyChanged("SelectedDienst");
				RaisePropertyChanged("IsEditEnabled");

                if (value == null)
                {
                    DienstZeiten = null;
                    return;
                }

                var da = GetService<IDiensteDataAccess>();
                DienstZeiten = da.GetDienstZeiten(value.DienstID);
                if (DienstZeiten != null && DienstZeiten.Count() > 0)
                    DienstZeiten.First().IsExpanded = true;
    		}
    	}

		IList<OptionValue> _dienstTypen;
		public IList<OptionValue> DienstTypen
		{
			get
			{
				if (_dienstTypen == null)
				{
					//get the data access via the service locator.
					var da = GetService<IDiensteDataAccess>();
					var lst = da.GetDienstTyp();
					_dienstTypen = lst != null ? new ObservableCollection<OptionValue>(lst) : new ObservableCollection<OptionValue>();
				}
				return _dienstTypen;
			}
		}

        IEnumerable<DienstZeitCollection> _dienstZeiten;
        public IEnumerable<DienstZeitCollection> DienstZeiten
        {
            get
            {
                return _dienstZeiten;
            }
            set
            {
                _dienstZeiten = value;
                RaisePropertyChanged("DienstZeiten");
            }
        }

		public bool IsEditEnabled
		{
			get
			{
				return SelectedDienst != null;
			}
		}

        #endregion
    }
}
